package hms.UserAccountsModule;

import hms.database.DAOnoGUI;
import hms.database.DBRowList;
import hms.database.DBRowObject;
import hms.employees.Employee;
import hms.employees.EmployeeControl;
import hms.employees.JobTitleList;
import hms.employees.TerminationReasonList;
import hms.permissions.*;

public class userAccountTest {
	// Print database table
	public static <ListElement extends DBRowObject> void printTable(String title, DBRowList<ListElement> list) {
		System.out.println(title);
		if(list.isEmpty()) {
			System.out.println("List is empty");	
		} else {
			for(ListElement element : list) {
				System.out.println(element.getUniqueIdentifier()+": "+element);
			}
			System.out.println();
		}
	}
	
	public static <ListElement extends DBRowObject> void cleanTable(DBRowList<ListElement> list) {
		for(ListElement element : list) {
			element.markToBeDeleted();
			element.commitToDatabase();
		}
	}
	
	public static void checkTables() {
		System.out.println("[CURRENT TABLE STATE]");
		UserAccountControl uaList = new UserAccountControl();
		printTable("User Accounts", uaList);
		EmployeeControl emList = new EmployeeControl();
		printTable("Employees",emList);
		TerminationReasonList trList = new TerminationReasonList();
		trList.fillFromDatabase();
		printTable("Termination Reasons",trList);
		JobTitleList jtList = new JobTitleList();
		jtList.fillFromDatabase();
		printTable("Job Titles",jtList);
	}
	
	// Database test
	public static void main(String[] args) {
		// Open database
		DAOnoGUI.getDAO();
		// Preliminary: Clean the DB tables
		{
			System.out.println("Cleaning tables...\n");
			

			UserAccountControl uaList = new UserAccountControl();
			cleanTable(uaList);
			
			EmployeeControl emList = new EmployeeControl();
			cleanTable(emList);
			
			TerminationReasonList trList = new TerminationReasonList();
			trList.fillFromDatabase();
			cleanTable(trList);
			
			JobTitleList jtList = new JobTitleList();
			jtList.fillFromDatabase();
			cleanTable(jtList);
		}
		// Black-box default check on Employee table.  This should create
		// a default job title and termination reason.  Checks to ensure
		// that foriegn-key oriented code and default creation is performing
		// correctly.
		
		System.out.println("Saving default Employee...");
		
		Employee ben = new Employee();
		ben.commitToDatabase();
		
		System.out.println("Saving default User Account...");
		
		UserAccount benAccount = new UserAccount();
		benAccount.setUsername("badcock");
		benAccount.setPassword("bananas");
		benAccount.commitToDatabase();
		checkTables();

		System.out.println("Changing details about employee...");
		
		ben.setFirstName("Ben");
		ben.setLastName("Adcock");
		ben.setPosition("Head Honcho");
		ben.setHireDate(2012, 04, 01);
		checkTables();
		ben.commitToDatabase();
		checkTables();
		
		System.out.println("Attempting rudimentary linking...");
		
		benAccount.linkToEmployee(ben);
		checkTables();
		
		System.out.println("More users...");
		
		UserAccount akilahAccount = new UserAccount();
		Employee akilah = new Employee();
		akilah.setFirstName("Akilah");
		akilah.setLastName("McIntyre");
		akilah.setPosition("CEO");
		akilahAccount.getPermissions().grantPermission(Permission.FULL_ACCESS);
		akilahAccount.setUsername("akilah");
		akilahAccount.setPassword("java");
		akilahAccount.linkToEmployee(akilah);
		
		UserAccount mattAccount = new UserAccount("mjohnson","dragonballz");
		mattAccount.getPermissions().grantPermission(Permission.RESERVE_ROOMS);
		mattAccount.getPermissions().grantPermission(Permission.CHECK_IN_OUT);
		Employee matt = mattAccount.getEmployee();
		matt.setFullname("Matt", "Johnson");
		matt.setTerminationReason("Excessive partying");
		matt.setHireDate(2012, 2, 10);
		matt.setTerminationDate(2012, 4, 4);
		mattAccount.commitToDatabase();
		checkTables();
		
		{
			UserAccountControl uac = new UserAccountControl();
			UserAccount bena = uac.getByUsername("badcock");
			// White Box - try checkPassword, then authenticate user
			
			// Test checkPassword with good password
			boolean test = bena.checkPassword("bananas");
			System.out.println(test?"Valid password case OK":"Valid password case BAD");
			
			// Test checkPassword with bad password
			test = bena.checkPassword("badpass");
			System.out.println(test?"Invalid password case BAD":"Invalid password case OK");
			
			// Test authenticateUser with good password
			test = uac.authenticateUser("badcock", "bananas")!=null;
			System.out.println(test?"Valid password from UAC OK":"Valid password from UAC BAD");
			
			// Test authenticateUser with bad password
			test = uac.authenticateUser("badcock", "badpassword")!=null;
			System.out.println(test?"Invalid password from UAC BAD":"Invalid password from UAC OK");
;		}
		
		DAOnoGUI.closeDAO();
		
		
		

	}
}
